package com.ruoyi.system.frontierEvent.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.SerialNoUtils;
import com.ruoyi.system.basicInformation.domain.TWfActivityInstance;

import com.ruoyi.system.basicInformation.service.ITAlarmService;
import com.ruoyi.system.basicInformation.service.ITWfActivityInstanceService;
import com.ruoyi.system.basicInformation.vo.TWfActivityInstanceVo;
import com.ruoyi.system.frontierEvent.bo.TAttachAddBo;
import com.ruoyi.system.frontierEvent.service.ITAttachService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.ruoyi.system.frontierEvent.bo.TEventAddBo;
import com.ruoyi.system.frontierEvent.bo.TEventQueryBo;
import com.ruoyi.system.frontierEvent.bo.TEventEditBo;
import com.ruoyi.system.frontierEvent.domain.TEvent;
import com.ruoyi.system.frontierEvent.mapper.TEventMapper;
import com.ruoyi.system.frontierEvent.vo.TEventVo;
import com.ruoyi.system.frontierEvent.service.ITEventService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 案件信息Service业务层处理
 *
 * @author ruoyi
 * @date 2021-05-19
 */
@Service
public class TEventServiceImpl extends ServiceImpl<TEventMapper, TEvent> implements ITEventService {
    @Autowired
    private ITAttachService iTAttachService;

    @Autowired
    private ITWfActivityInstanceService itWfActivityInstanceService;

    @Autowired
    private ITAlarmService iTAlarmService;

    @Override
    public TEventVo queryById(Long id) {
        TEvent db = this.baseMapper.selectById(id);
        return BeanUtil.toBean(db, TEventVo.class);
    }

    @Override
    public List<TEventVo> queryList(TEventQueryBo bo) {
        LambdaQueryWrapper<TEvent> lqw = Wrappers.lambdaQuery();
        List<TEventVo> eventVos = new ArrayList<>();
        //上报人
        if (bo.getReportUserId() != null && bo.getReportUserId() > 0) {
            lqw.eq(bo.getReportUserId() > 0, TEvent::getReporterObjectId, bo.getReportUserId());
            lqw.eq(StrUtil.isNotBlank(bo.getEvtState()), TEvent::getEvtState, bo.getEvtState());
            lqw.eq(StrUtil.isNotBlank(bo.getEvtType()), TEvent::getEvtType, bo.getEvtType());
            lqw.eq(StrUtil.isNotBlank(bo.getEvtSource()), TEvent::getEvtSource, bo.getEvtSource());
            lqw.eq(bo.getViolation() != null && bo.getViolation() > 0, TEvent::getViolation, bo.getViolation());
            lqw.eq(StrUtil.isNotBlank(bo.getAreaName()), TEvent::getAreaName, bo.getAreaName());
            if (bo.getReporterTime() != null) {
                Calendar calstart = java.util.Calendar.getInstance();
                calstart.setTime(bo.getReporterTime());
                calstart.add(Calendar.DATE, 1);
                calstart.add(Calendar.SECOND, -1);
                lqw.between(TEvent::getReporterTime, bo.getReporterTime(), calstart.getTime());
            }
            lqw.eq(1 == 1, TEvent::getDelFlag, 0);
            lqw.orderByDesc(TEvent::getId);
            eventVos = entity2Vo(this.list(lqw));
            //根据案件Id查询附件列表
            if (bo.getReportUserId() != null && bo.getReportUserId() > 0) {
                for (int i = 0; i < eventVos.size(); i++) {
                    //查询环节列表
                    List<TWfActivityInstanceVo> tWfActivityInstanceVos = itWfActivityInstanceService.caseQueryById(eventVos.get(i).getId());
                    eventVos.get(i).setActivityInstanceVoList(tWfActivityInstanceVos);
                    for (int j = 0; j < tWfActivityInstanceVos.size(); j++) {
                        //查询附件列表
                        eventVos.get(i).setAttachIds(iTAttachService.queryCaseAttachList(eventVos.get(i).getId(), tWfActivityInstanceVos.get(j).getId()));
                    }
                }
            }
        } else if ((bo.getReportUserId() != null && bo.getOperatorUserId() > 0) || (bo.getReceiveUserId() != null && bo.getReceiveUserId() > 0)) {
            eventVos = baseMapper.querypPatrolList(bo.getOperatorUserId(), bo.getReceiveUserId(), bo.getEvtState());
            //根据案件Id查询附件列表
            if (bo.getReportUserId() != null && bo.getReportUserId() > 0) {
                for (int i = 0; i < eventVos.size(); i++) {
                    //查询环节列表
                    List<TWfActivityInstanceVo> tWfActivityInstanceVos = itWfActivityInstanceService.caseQueryById(eventVos.get(i).getId());
                    eventVos.get(i).setActivityInstanceVoList(tWfActivityInstanceVos);
                    for (int j = 0; j < tWfActivityInstanceVos.size(); j++) {
                        //查询附件列表
                        eventVos.get(i).setAttachIds(iTAttachService.queryCaseAttachList(eventVos.get(i).getId(), tWfActivityInstanceVos.get(j).getId()));
                    }
                }
            }
        } else {
            eventVos = this.baseMapper.querypList(bo);
            //导出不需要作此操作
            if (!bo.getIsExport()) {
                //根据案件Id查询附件列表
                for (int i = 0; i < eventVos.size(); i++) {
                    //查询环节列表
                    List<TWfActivityInstanceVo> tWfActivityInstanceVos = itWfActivityInstanceService.caseQueryById(eventVos.get(i).getId());
                    eventVos.get(i).setActivityInstanceVoList(tWfActivityInstanceVos);
                    for (int j = 0; j < tWfActivityInstanceVos.size(); j++) {
                        //查询附件列表
                        if(Validator.isNotNull(eventVos.get(i).getAttachIds())){
                            eventVos.get(i).getAttachIds().addAll(iTAttachService.queryCaseAttachList(eventVos.get(i).getId(), tWfActivityInstanceVos.get(j).getId()));
                        }else{
                            eventVos.get(i).setAttachIds(iTAttachService.queryCaseAttachList(eventVos.get(i).getId(), tWfActivityInstanceVos.get(j).getId()));
                        }
                    }
                }
            }
        }

        return eventVos;
    }

    @Override
    public List<TEventVo> queryAuditList(TEventQueryBo bo) {
        List<TEventVo> eventVos = new ArrayList<>();
        eventVos = this.baseMapper.queryAuditList(bo);
        //根据案件Id查询附件列表
        for (int i = 0; i < eventVos.size(); i++) {
            //查询环节列表
            List<TWfActivityInstanceVo> tWfActivityInstanceVos = itWfActivityInstanceService.caseQueryById(eventVos.get(i).getId());
            eventVos.get(i).setActivityInstanceVoList(tWfActivityInstanceVos);
            for (int j = 0; j < tWfActivityInstanceVos.size(); j++) {
                //查询附件列表
                eventVos.get(i).setAttachIds(iTAttachService.queryCaseAttachList(eventVos.get(i).getId(), tWfActivityInstanceVos.get(j).getId()));
            }
        }
        return eventVos;
    }

    @Override
    public List<TEventVo> queryAuditListForMap(TEventQueryBo bo) {
        List<TEventVo> eventVos = new ArrayList<>();
        eventVos = this.baseMapper.queryAuditListForMap(bo);
        //根据案件Id查询附件列表
        for (int i = 0; i < eventVos.size(); i++) {
            //查询环节列表
            List<TWfActivityInstanceVo> tWfActivityInstanceVos = itWfActivityInstanceService.caseQueryById(eventVos.get(i).getId());
            eventVos.get(i).setActivityInstanceVoList(tWfActivityInstanceVos);
            for (int j = 0; j < tWfActivityInstanceVos.size(); j++) {
                //查询附件列表
                eventVos.get(i).setAttachIds(iTAttachService.queryCaseAttachList(eventVos.get(i).getId(), tWfActivityInstanceVos.get(j).getId()));
            }
        }
        return eventVos;
    }

    @Override
    public List<TEventVo> listEventInfoSourceStatistics(TEventQueryBo bo) {
        return this.baseMapper.listEventInfoSourceStatistics(bo);
    }

    @Override
    public List<TEventVo> listViolationStatistics(TEventQueryBo bo) {
        List<TEventVo> tTerminalVoList = this.baseMapper.listViolationStatistics(bo);
//        for (TEventVo str : tTerminalVoList) {
//            str.setChildren(this.baseMapper.listViolationStatisticsCh(str.getViolation()));
//        }
        return tTerminalVoList;
    }

    @Override
    public List<TEventVo> typeStatistics(TEventQueryBo bo) {
        return this.baseMapper.typeStatistics(bo);
    }

    @Override
    public List<TEventVo> analysisStatistics(TEventQueryBo bo) {
        return this.baseMapper.analysisStatistics(bo);
    }

    @Override
    public List<TEventVo> policeInformationStatistics(TEventQueryBo bo) {
        return this.baseMapper.policeInformationStatistics(bo);
    }

    @Override
    public List<TEventVo> policeLevelStatistics(TEventQueryBo bo) {
        return this.baseMapper.policeLevelStatistics(bo);
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<TEventVo> entity2Vo(Collection<TEvent> collection) {
        List<TEventVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, TEventVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<TEvent> page = (Page<TEvent>) collection;
            Page<TEventVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Boolean insertByAddBo(TEventAddBo bo) {
        bo.setEvtState("1");
        boolean save = false;
        try {
            TEvent add = BeanUtil.toBean(bo, TEvent.class);
            add.setEvtCode(SerialNoUtils.generateSerialNo());
            validEntityBeforeSave(add);
            //新增案件
            this.save(add);
            TWfActivityInstance activityInstance = new TWfActivityInstance();
            activityInstance.setEvtId(add.getId());
            activityInstance.setEvtState(new Long(1));
            //新增案件流程
            itWfActivityInstanceService.save(activityInstance);
            if (add.getId() != 0 && activityInstance.getId() != 0 && bo.getAttachIds().size() > 0) {
                //新增附件记录
                for (int i = 0; i < bo.getAttachIds().size(); i++) {
                    TAttachAddBo tAttachAddBo = new TAttachAddBo();
                    tAttachAddBo.setEvtId(add.getId());
                    tAttachAddBo.setEvtActType(new Long(1));
                    tAttachAddBo.setFileId(bo.getAttachIds().get(i));
                    tAttachAddBo.setFileName(bo.getFileNameList().get(i));
                    tAttachAddBo.setEvtWfId(activityInstance.getId());
                    save = iTAttachService.insertByAddBo(tAttachAddBo);
                }
            } else {
                throw new BaseException("案件上报失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException("案件上报失败");
        }
        return save;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean alarmAddEvtInfo(TEventAddBo bo) {
        bo.setEvtState("1");
        boolean save = false;
        try {
            TEvent add = BeanUtil.toBean(bo, TEvent.class);
            add.setEvtCode(SerialNoUtils.generateSerialNo());
            validEntityBeforeSave(add);

            //新增案件
            this.save(add);
            TWfActivityInstance activityInstance = new TWfActivityInstance();
            activityInstance.setEvtId(add.getId());
            activityInstance.setEvtState(new Long(1));
            //新增案件流程
            itWfActivityInstanceService.save(activityInstance);

            activityInstance.setReceiveObjectId(bo.getReceiveObjectId());
            activityInstance.setEvtState(new Long(2));
            //新增案件流程
            save = itWfActivityInstanceService.save(activityInstance);

            this.baseMapper.updateAlarmByIdForIssue(bo.getAlarmId(), add.getId(), bo.getEvtSource());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException("案件上报失败");
        }
        return save;
    }

    @Override
    public Boolean updateByEditBo(TEventEditBo bo) {
        boolean state = false;
        try {
            TEvent update = BeanUtil.toBean(bo, TEvent.class);
            TWfActivityInstance tWfActivityInstance;
            //修改案件信息和结案归档修改案件状态
            if ("1".equals(bo.getUpdateType())) {
                state = this.baseMapper.updateById(update) > 0;
            } else if ("2".equals(bo.getUpdateType())) {
                //下发并生成已处置环节
                tWfActivityInstance = new TWfActivityInstance();
                tWfActivityInstance.setEvtId(bo.getId());
                tWfActivityInstance.setEvtState(new Long(2));
                tWfActivityInstance.setReceiveObjectId(bo.getReceiveObjectId());
                state = itWfActivityInstanceService.save(tWfActivityInstance);
            } else if ("3".equals(bo.getUpdateType())) {
                //处置修改案件状态和环节新增加一条归档环节
                update.setEvtState("2");
                this.baseMapper.updateById(update);
                tWfActivityInstance = new TWfActivityInstance();
                tWfActivityInstance.setEvtId(bo.getId());
                tWfActivityInstance.setEvtState(new Long(3));
                tWfActivityInstance.setOperatorObjectId(bo.getOperatorObjectId());
                state = itWfActivityInstanceService.save(tWfActivityInstance);
            } else {
                //其他案件信息
                state = this.baseMapper.updateById(update) > 0;
            }
        } catch (Exception e) {
            throw new BaseException("案件修改失败");
        }
        return state;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TEvent entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

    @Override
    public List<TEventVo> querypListForExport(TEventQueryBo bo) {
        return this.baseMapper.querypListForExport(bo);
    }
}
